package com.aeye.mbr.common.template.engine;

import com.aeye.mbr.common.exception.TalkeduException;
import com.aeye.mbr.common.util.StringUtils;
import org.apache.commons.io.IOUtils;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Velocity模板引擎
 */
public class VelocityTemplateEngine implements TemplateEngine {

    private static Logger log = LoggerFactory.getLogger(VelocityTemplateEngine.class);


    VelocityEngine mEngine = null;

    Map<String, Object> mToolbox = null;

    public VelocityTemplateEngine() {
        initEngine();
        //initToolbox();
    }


    private void initEngine() {
        try {
            Properties p = new Properties();
            p.put(VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.Log4JLogChute");
            p.put(VelocityEngine.RUNTIME_LOG_LOGSYSTEM + ".log4j.logger", "console");
            mEngine = new VelocityEngine();
            mEngine.init(p);
        } catch (Exception e) {
            log.error("初始化VelocityEngine失败!", e);
        }
    }

    public void initToolbox(Map<String, Object> toolbox) {
        if (mToolbox == null) {
            mToolbox = new HashMap<>();
        }
        if (toolbox != null) {
            for (String key : toolbox.keySet()) {
                mToolbox.put(key, toolbox.get(key));
            }
        }
    }

    @SuppressWarnings("unchecked")
    protected <T extends Object> T get(VelocityContext context, String key) {
        return context != null ? (T) context.get(key) : null;
    }

    public VelocityContext createVelocityContext() {
        VelocityContext context = new VelocityContext();
        if(mToolbox != null){
            for (Map.Entry<String, Object> entry : this.mToolbox.entrySet()) {
                context.put(entry.getKey(), entry.getValue());
            }
        }
        return context;
    }


    @Override
    public String merge(String template, Map<String, Object> params) {
        VelocityContext context = createVelocityContext();
        if (params != null) {
            for (String key : params.keySet()) {
                context.put(key, params.get(key));
            }
        }
        return merge(context, template);
    }

    @Override
    public boolean checkTemplateSyntax(String template) {
        try {
            merge(template, new HashMap<String, Object>());
            return true;
        } catch (Exception e) {

        }
        return false;
    }

    /**
     * 合并字符串模板
     *
     * @param context
     * @param template
     * @return
     */
    public String merge(VelocityContext context, String template) {
        log.debug("merge之前:" + template);
        StringWriter writer = null;
        try {
            if (StringUtils.isNotEmpty(template) && context != null) {
                writer = new StringWriter();
                // 转换输出
                mEngine.evaluate(context, writer, this.getClass().getSimpleName(), template); // 关键方法
                writer.flush();
                template = writer.toString();
            }
        } catch (Exception e) {
            log.error("Velocity merge出现错误!", e);
            throw new TalkeduException("merge模板出现异常!");
        } finally {
            IOUtils.closeQuietly(writer);
        }
        log.debug("merge之后:" + template);
        return template;
    }
}
